
// Copyright (C) Recursion Company. All rights reserved.

#include "stdafx.h"
#include "vol_user_app_info.h"

//-----------------------------------------------------------------------------------------

CVWnd_PicButton::CVWnd_PicButton ()
{
    m_npButtonType = 0;
    m_blpPressed = FALSE;
    m_clrTransColor = m_clrBack = CLR_DEFAULT;
    m_npCurrentBitmapIndex = VWPB_NORMAL_BITMAP;
}

BOOL CVWnd_PicButton::CreateControl (CVolNativeWndCreateParam* pCreateParam)
{
    if (_CREATE_WND_BY_PARAM (pCreateParam) != NULL)
    {
        UpdateButtonShape (FALSE);
        SetPressState (m_blpPressed);
        return TRUE;
    }

    return FALSE;
}

void CVWnd_PicButton::OnLButtonDown (UINT nFlags, CPoint point)
{
    CRect rtClient;
    GetClientRect (&rtClient);

    if (rtClient.PtInRect (point) && IsWindowEnabled () && m_npButtonType == 0)
    {
        Draw (VWPB_PRESSED_BITMAP);

        if (::GetCapture () != m_hWnd)
            SetCapture ();
    }
}

void CVWnd_PicButton::OnLButtonUp (UINT nFlags, CPoint point)
{
    ::ReleaseCapture ();

    CRect rtClient;
    GetClientRect (&rtClient);

    if (rtClient.PtInRect (point) && IsWindowEnabled ())
    {
        if (m_npButtonType == 1)
            SetPressState (!m_blpPressed);
        else
            Draw (VWPB_NORMAL_BITMAP);

        if (m_pEventListener != NULL)
            m_pEventListener->OnClick ();
    }
}

void CVWnd_PicButton::SetPressState (const BOOL_P blpPressed)
{
    if (m_npButtonType == 1)
    {
        m_blpPressed = blpPressed;
        Draw (m_blpPressed ? VWPB_PRESSED_BITMAP : VWPB_NORMAL_BITMAP);
    }
}

void CVWnd_PicButton::OnMouseMove (UINT nFlags, CPoint point)
{
    if (m_npButtonType == 1 || IsWindowEnabled () == FALSE)
    {
        ::ReleaseCapture ();
        return;
    }

    CRect rtClient;
    GetClientRect (&rtClient);
    const BOOL_P blpInWndRect = rtClient.PtInRect (point);

    ClientToScreen (&point);
    HWND hWnd = ::WindowFromPoint (point);

    if (hWnd == m_hWnd || (hWnd == NULL && blpInWndRect))
    {
        if (::GetCapture () != m_hWnd)
            SetCapture ();

        Draw ((nFlags & MK_LBUTTON) != 0 ? VWPB_PRESSED_BITMAP : VWPB_HIGHLIGHT_BITMAP);
    }
    else
    {
        if ((nFlags & MK_LBUTTON) == 0)
            ::ReleaseCapture ();
        Draw (VWPB_NORMAL_BITMAP);
    }
}

void CVWnd_PicButton::OnPaint (HDC hNotUsed)
{
    CPaintDC dc (m_hWnd);

    CRect rtClient;
    GetClientRect (&rtClient);
    const INT nWidth = rtClient.Width ();
    const INT nHeight = rtClient.Height ();

    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap (dc, nWidth, nHeight);

    CDC dcMem;
    dcMem.CreateCompatibleDC (dc);
    HBITMAP hOldBitmap = dcMem.SelectBitmap (bitmap);

    CBrush brhBack;
    brhBack.CreateSolidBrush (GetRealBackColor (m_clrBack));
	HBRUSH hOldBrush = dcMem.SelectBrush (brhBack);
    dcMem.PatBlt (0, 0, nWidth, nHeight, PATCOPY);
	dcMem.SelectBrush (hOldBrush);

    const HBITMAP hBitmap = GetHBitmap ();
    if (hBitmap != NULL)
    {
        BITMAP infBitmap;
        ::GetObject ((HGDIOBJ)hBitmap, sizeof (infBitmap), &infBitmap);

        HDC hMemDC = ::CreateCompatibleDC (dc.m_hDC);
        HBITMAP hOldBitmap = (HBITMAP)::SelectObject (hMemDC, hBitmap);
        ::SetStretchBltMode (dcMem.m_hDC, COLORONCOLOR);
        ::AlphaStretchBitmap (dcMem.m_hDC, 0, 0, nWidth, nHeight, hMemDC, infBitmap);
        ::SelectObject (hMemDC, hOldBitmap);
        ::DeleteDC (hMemDC);
    }

    dc.BitBlt (0, 0, nWidth, nHeight, dcMem, 0, 0, SRCCOPY);
    dcMem.SelectBitmap (hOldBitmap);
}

HBITMAP CVWnd_PicButton::GetHBitmap ()
{
    ASSERT (m_npCurrentBitmapIndex >= 0 && m_npCurrentBitmapIndex < NUM_ELEMENTS_OF (m_aobjBitmaps));

    HBITMAP hBitmap = (HBITMAP)m_aobjBitmaps [m_npCurrentBitmapIndex];

    if (IsWindowEnabled () == FALSE && (HBITMAP)m_aobjBitmaps [VWPB_DISABLED_BITMAP] != NULL)
        hBitmap = (HBITMAP)m_aobjBitmaps [VWPB_DISABLED_BITMAP];

    if (hBitmap == NULL)
        hBitmap = (HBITMAP)m_aobjBitmaps [VWPB_NORMAL_BITMAP];

    return hBitmap;
}

void CVWnd_PicButton::Draw (const INT_P npBitmapIndex)
{
    ASSERT (npBitmapIndex >= 0 && npBitmapIndex < NUM_ELEMENTS_OF (m_aobjBitmaps));

    if (m_npCurrentBitmapIndex != npBitmapIndex)
    {
        m_npCurrentBitmapIndex = npBitmapIndex;
        UpdateButtonShape (TRUE);
    }
}

void CVWnd_PicButton::OnEnable (BOOL bEnable) 
{
    UpdateButtonShape (TRUE);
    SetMsgHandled (FALSE);
}

void CVWnd_PicButton::UpdateButtonShape (const BOOL_P blpUpdateAtonce)
{
    if (m_hWnd == NULL)
        return;

    if (m_rgnShape.m_hRgn != NULL)
        m_rgnShape.DeleteObject ();

    if (m_clrTransColor != CLR_DEFAULT)
    {
        HBITMAP hBitmap = GetHBitmap ();
        if (hBitmap != NULL)
        {
            HRGN hRgn = BitmapToRegion (hBitmap, m_clrTransColor);
            if (hRgn != NULL)
            {
                m_rgnShape.Attach (hRgn);
                ::SetWindowRgn (m_hWnd, hRgn, TRUE);
            }
        }
    }

    if ((HRGN)m_rgnShape == NULL)
        ::SetWindowRgn (m_hWnd, NULL, TRUE);

    Invalidate ();
    if (blpUpdateAtonce)
        UpdateWindow ();
}

void CVWnd_PicButton::TakeOverBitmap (const INT_P npBitmapIndex, const HBITMAP hBitmap)
{
    ASSERT (npBitmapIndex >= 0 && npBitmapIndex < NUM_ELEMENTS_OF (m_aobjBitmaps));

    m_aobjBitmaps [npBitmapIndex].Attach (hBitmap);
    UpdateButtonShape (TRUE);
}

void CVWnd_PicButton::SetTransColor (const COLORREF clrTransColor)
{
    if (m_clrTransColor != clrTransColor)
    {
        m_clrTransColor = clrTransColor;
        UpdateButtonShape (TRUE);
    }
}
